<?php
/**
 * Here is your custom functions.
 */

use support\Cache;
use Firebase\JWT\BeforeValidException;
use Firebase\JWT\ExpiredException;
use Firebase\JWT\JWT;
use Firebase\JWT\Key;
use Firebase\JWT\SignatureInvalidException;

if (! function_exists('cache')) {
    function cache()
    {
        $arguments = func_get_args();

        if (empty($arguments)) {
            return Cache::instance();
        }

        if (is_string($arguments[0])) {
            return Cache::get(...$arguments);
        }

        if (! is_array($arguments[0])) {
            throw new InvalidArgumentException(
                'When setting a value in the cache, you must pass an array of key / value pairs.'
            );
        }
        return Cache::set(key($arguments[0]), reset($arguments[0]), $arguments[1] ?? null);
    }
}


/**
 * token验证
 * @param $jwt
 * @return array
 */
function decode_auth_token($jwt)
{
    $auth_key = config('admin.jwt_auth_key');
    $res = [
        'code' => 0,
        'msg'  => 'error',
        'data' => null
    ];
    try {
//        JWT::$leeway = config('admin.token_leeway_time'); //一小时有效
        $decoded = JWT::decode($jwt,new Key($auth_key, 'HS256'));
        $res['data'] = $decoded->data;
        $res['code'] = 1;
        $res['msg'] = 'ok';
    } catch (SignatureInvalidException $e) {    //签名不正确
        $res['msg'] = '签名不正确';
        $res['data'] = $e->getMessage();
    } catch (BeforeValidException $e) {     //签名在某个时间点之后才能用
        $res['msg'] = '签名在某个时间点之后才能用';
        $res['data'] = $e->getMessage();
    } catch (ExpiredException $e) {     // token过期
        $res['msg'] = '请重新登录';
        $res['code'] = 2;
        $res['data'] = $e->getMessage();
    } catch (Exception $e) {    //其他错误
        $res['msg'] = 'token错误';
        $res['data'] = $e->getMessage();
    }
    return $res;
}

/**
 * 生成token
 * @param $data
 * @return string
 */
function generate_user_token($data)
{
    $currentTime    = time();
    $leewayTime = config('admin.token_leeway_time');
    $expireTime     = $currentTime + $leewayTime;
    //缓存中无信息

    $key = config('admin.jwt_auth_key');
    $token = array(
        "iss" => 'myshop', //签发者
        "aud" => 'myshop', //接受者
        "iat" => $currentTime, //签发时间
        "nbf" => $currentTime, //该时间后可访问
//        "exp" => $expireTime, //过期时间，1小时
        "data" => $data
    );

    return JWT::encode($token, $key, 'HS256');
}

/**
 * 密码加密方法
 * @param string $pw 要加密的原始密码
 * @param string $authCode 加密字符串
 * @return string
 */
function set_password($pw, $authCode = '')
{
    if (empty($authCode)) {
        $authCode = config('admin.jwt_auth_key');
    }
    return "###" . md5(md5($authCode . $pw));
}
/**
 * 密码比较方法,所有涉及密码比较的地方都用这个方法
 * @param string $password 要比较的密码
 * @param string $passwordInDb 数据库保存的已经加密过的密码
 * @return boolean 密码相同，返回true
 */
function compare_password($password, $passwordInDb)
{
    return set_password($password) == $passwordInDb;
}
/**
 * 操作成功返回的快捷方法
 * @access protected
 * @param mixed $msg 提示信息
 * @param mixed $data 返回的数据
 */
function success($msg = '', $data = '', $paginate=false)
{
    $code = 200;
    if($paginate){
        $data = [
            'list' => $data->items(),
            'total' => $data->total(),
            'page' => $data->currentPage(),
            'last_page' => $data->lastPage()
        ];
    }
    return json( [
        'code' => $code,
        'msg' => $msg,
        'data' => $data,
    ]);
}

/**
 * 操作错误返回的快捷方法
 * @access protected
 * @param mixed $msg 提示信息,若要指定错误码,可以传数组,格式为['code'=>您的错误码,'msg'=>'您的错误消息']
 * @param mixed $data 返回的数据
 * @param mixed $code 返回的错误码
 */
function error($msg = '', $data = '', $code = 0)
{
    if (is_array($msg)) {
        $code = $msg['code'];
        $msg = $msg['msg'];
    }
    return json( [
        'code' => $code,
        'msg' => $msg,
        'data' => $data,
    ]);
}

function getTree($arr,$pid = 0,$parent_id='pid', $id='id', $child = 'children')
{
    $res = [];
    foreach($arr as $v){
        if($v[$parent_id] ==$pid){
            $childs = getTree($arr,$v[$id],$parent_id,$id, $child);
            $v[$child]=$childs;
            $res[]=$v;
        }
    }
    return $res;
}

function getChilds($arr, $pid, $parent_id='parent_id', $id='id'){
    $res = [$pid];
    foreach ($arr as $v){
        if($v[$parent_id] == $pid){
            $res = array_merge($res, getChilds($arr, $v[$id], $parent_id, $id));
        }
    }
    return $res;
}



/**
 * 获得系统根目录
 * @return string
 */
function get_root_path()
{
    return dirname(realpath(dirname($_SERVER['SCRIPT_FILENAME'])));
}

/**
 * 自定义验证手机号、电话合法性
 * @access protected
 * @param mixed $value 字段值
 * @param mixed $rule 验证规则
 * @return bool
 */
function checkPhone($value)
{
    if (preg_match("/^([0-9]{3,4}-)?[0-9]{7,8}$/", $value)) {
        return true;
    } elseif (preg_match('/(^(13\d|15[^4\D]|17[013678]|18\d|199)\d{8})$/', $value)) {
        return true;
    } else {

        return false;
    }
}


/**
 * @description:根据数据
 * @param {dataArr:需要分组的数据；keyStr:分组依据}
 * @return:
 */
function dataGroup(array $dataArr, string $keyStr)   :array
{
    $newArr=[];
    foreach ($dataArr as $k => $val) {    //数据根据日期分组
        $newArr[$val[$keyStr]][] = $val;
    }
    return $newArr;
}



/**
 * 获取文件扩展名
 * @param string $filename 文件名
 * @return string 文件扩展名
 */
function get_file_extension($filename)
{
    $pathinfo = pathinfo($filename);
    return strtolower($pathinfo['extension']);
}
